home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / dalla rivista / host contacted / jikes.lha / jikes-1.11 / src / jcl / jcl_iclass.cpp < prev    next >
C/C++ Source or Header  |  1999-12-09  |  14KB  |  541 lines

  1. // $Id: jcl_iclass.cpp,v 1.2 1999/12/09 18:02:26 lord Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler
  4. // License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10. #include <iostream.h>
  11. #include <string.h>
  12. #include "jcl_iclass.h"
  13.  
  14.  
  15. inline u1 InputClassFile::get_u1()
  16. {
  17.     int c = getc(classfile);
  18.     if (c == EOF)
  19.     {
  20. cerr << "END-OF-FILE REACHED PREMATURELY !!!\n";
  21.         /* crash !!! */
  22.     }
  23.     return (u1) c;
  24. }
  25.  
  26.  
  27. inline u2 InputClassFile::get_u2()
  28. {
  29.     u2 i = get_u1();
  30.     return (i << 8) + get_u1();
  31. }
  32.  
  33.  
  34. inline u4 InputClassFile::get_u4()
  35. {
  36.     u4 i = get_u1();
  37.     i = (i << 8) + get_u1();
  38.     i = (i << 8) + get_u1();
  39.     return (i << 8) + get_u1();
  40. }
  41.  
  42.  
  43.  
  44. CONSTANT_Class_info *InputClassFile::get_CONSTANT_Class(u1 &tag)
  45. {
  46.     CONSTANT_Class_info *p = new CONSTANT_Class_info(tag);
  47.  
  48.     p -> name_index = get_u2();
  49.  
  50.     return p;
  51. }
  52.  
  53.  
  54. CONSTANT_Fieldref_info *InputClassFile::get_CONSTANT_Fieldref(u1 &tag)
  55. {
  56.     CONSTANT_Fieldref_info *p = new CONSTANT_Fieldref_info(tag);
  57.  
  58.     p -> class_index = get_u2();
  59.     p -> name_and_type_index = get_u2();
  60.  
  61.     return p;
  62. }
  63.  
  64.  
  65. CONSTANT_Methodref_info *InputClassFile::get_CONSTANT_Methodref(u1 &tag)
  66. {
  67.     CONSTANT_Methodref_info *p = new CONSTANT_Methodref_info(tag);
  68.  
  69.     p -> class_index = get_u2();
  70.     p -> name_and_type_index = get_u2();
  71.  
  72.     return p;
  73. }
  74.  
  75.  
  76. CONSTANT_InterfaceMethodref_info *InputClassFile::get_CONSTANT_InterfaceMethodref(u1 &tag)
  77. {
  78.     CONSTANT_InterfaceMethodref_info *p = new CONSTANT_InterfaceMethodref_info(tag);
  79.  
  80.     p -> class_index = get_u2();
  81.     p -> name_and_type_index = get_u2();
  82.  
  83.     return p;
  84. }
  85.  
  86.  
  87.  
  88. CONSTANT_String_info *InputClassFile::get_CONSTANT_String(u1 &tag)
  89. {
  90.     CONSTANT_String_info *p = new CONSTANT_String_info(tag);
  91.  
  92.     p -> string_index = get_u2();
  93.  
  94.     return p;
  95. }
  96.  
  97.  
  98. CONSTANT_Integer_info *InputClassFile::get_CONSTANT_Integer(u1 &tag)
  99. {
  100.     CONSTANT_Integer_info *p = new CONSTANT_Integer_info(tag);
  101. #ifdef TBSL
  102.         // first cut by ds at using value directly
  103.         unsigned char  bytes[4];
  104.         int i;
  105.         unsigned uv;
  106.         for (i=0;i<4;i++) bytes[i] = get_u1();
  107. //    bytes = get_u4();
  108.                  uv = bytes[0];
  109.         for (i=1;i<4;i++) uv = uv << 8 | bytes[i];
  110.                    
  111.         p->value = (int) uv; 
  112. #endif
  113.         p->bytes = get_u4();
  114.     return p;
  115. }
  116.  
  117.  
  118. CONSTANT_Float_info *InputClassFile::get_CONSTANT_Float(u1 &tag)
  119. {
  120.     CONSTANT_Float_info *p = new CONSTANT_Float_info(tag);
  121.  
  122.     p -> bytes = get_u4();
  123.  
  124.     return p;
  125. }
  126.  
  127.  
  128. CONSTANT_Long_info *InputClassFile::get_CONSTANT_Long(u1 &tag)
  129. {
  130.     CONSTANT_Long_info *p = new CONSTANT_Long_info(tag);
  131.  
  132.     p -> high_bytes = get_u4();
  133.     p -> low_bytes = get_u4();
  134.  
  135.     return p;
  136. }
  137.  
  138.  
  139. CONSTANT_Double_info *InputClassFile::get_CONSTANT_Double(u1 &tag)
  140. {
  141.     CONSTANT_Double_info *p = new CONSTANT_Double_info(tag);
  142.  
  143.     p -> high_bytes = get_u4();
  144.     p -> low_bytes = get_u4();
  145.  
  146.     return p;
  147. }
  148.  
  149. CONSTANT_NameAndType_info *InputClassFile::get_CONSTANT_NameAndType(u1 &tag)
  150. {
  151.     CONSTANT_NameAndType_info *p = new CONSTANT_NameAndType_info(tag);
  152.  
  153.     p -> name_index = get_u2();
  154.     p -> descriptor_index = get_u2();
  155.  
  156.     return p;
  157. }
  158.  
  159. CONSTANT_Utf8_info *InputClassFile::get_CONSTANT_Utf8(u1 &tag)
  160. {
  161.     CONSTANT_Utf8_info *p = new CONSTANT_Utf8_info(tag);
  162.  
  163.     p -> length_ = get_u2();
  164.     p -> bytes = new char[p -> length() + 1];
  165.  
  166.     for (int i = 0; i < p -> length(); i++)
  167.          p -> bytes[i] = get_u1();
  168.     p -> bytes[p -> length()] = '\0';
  169.  
  170.     return p;
  171. }
  172.  
  173. cp_info *InputClassFile::get_cp_info()
  174. {
  175.     u1 tag = get_u1();
  176.  
  177.     switch(tag)
  178.     {
  179.         case CONSTANT_Class:
  180.              return get_CONSTANT_Class(tag);
  181.              break;
  182.         case CONSTANT_Fieldref:
  183.              return get_CONSTANT_Fieldref(tag);
  184.              break;
  185.         case CONSTANT_Methodref:
  186.              return get_CONSTANT_Methodref(tag);
  187.              break;
  188.         case CONSTANT_String:
  189.              return get_CONSTANT_String(tag);
  190.              break;
  191.         case CONSTANT_Integer:
  192.              return get_CONSTANT_Integer(tag);
  193.              break;
  194.         case CONSTANT_Float:
  195.              return get_CONSTANT_Float(tag);
  196.              break;
  197.         case CONSTANT_Long:
  198.              return get_CONSTANT_Long(tag);
  199.              break;
  200.         case CONSTANT_Double:
  201.              return get_CONSTANT_Double(tag);
  202.              break;
  203.         case CONSTANT_InterfaceMethodref:
  204.              return get_CONSTANT_InterfaceMethodref(tag);
  205.              break;
  206.         case CONSTANT_NameAndType:
  207.              return get_CONSTANT_NameAndType(tag);
  208.              break;
  209.         case CONSTANT_Utf8:
  210.              return get_CONSTANT_Utf8(tag);
  211.              break;
  212.         default:
  213. cerr << "CODE \"" << (int) tag << "\" is an invalid tag !!!\n";
  214.              break;
  215.     }
  216.  
  217.     return NULL;
  218. }
  219.  
  220.  
  221. SourceFile_attribute *InputClassFile::get_SourceFile_attribute(u2 &name_index, u4 &length)
  222. {
  223.     SourceFile_attribute *p = new SourceFile_attribute(name_index, length);
  224.  
  225.     p -> sourcefile_index = get_u2();
  226.  
  227.     return p;
  228. }
  229.  
  230.  
  231. Exceptions_attribute *InputClassFile::get_Exceptions_attribute(u2 &name_index, u4 &length)
  232. {
  233.     Exceptions_attribute *p = new Exceptions_attribute(name_index, length);
  234.  
  235.     u2 number_of_exceptions = get_u2();
  236.  
  237.     p -> exception_index_table.resize(number_of_exceptions);
  238.     for (int i = 0; i < number_of_exceptions; i++)
  239.         p -> exception_index_table[i] = get_u2();
  240.  
  241.     return p;
  242. }
  243.  
  244.  
  245. ConstantValue_attribute *InputClassFile::get_ConstantValue_attribute(u2 &name_index, u4 &length)
  246. {
  247.     ConstantValue_attribute *p = new ConstantValue_attribute(name_index, length);
  248.  
  249.     p -> constantvalue_index = get_u2();
  250.  
  251.     return p;
  252. }
  253.  
  254.  
  255. Code_attribute *InputClassFile::get_Code_attribute(u2 &name_index, u4 &length)
  256. {
  257.     Code_attribute *p = new Code_attribute(name_index, length);
  258.  
  259.     p -> max_stack = get_u2();
  260.     p -> max_locals = get_u2();
  261.  
  262.     u4 code_length;
  263.     code_length = get_u4();
  264.     p -> code.resize(code_length);
  265.     int i;
  266.     for (i = 0; i < code_length; i++)
  267.         p -> code[i] = get_u1();
  268.     u2 exception_table_length = get_u2();
  269.     p -> exception_table.resize(exception_table_length);
  270.     for (i = 0; i < exception_table_length; i++)
  271.     {
  272.         p -> exception_table[i].start_pc   = get_u2();
  273.         p -> exception_table[i].end_pc     = get_u2();
  274.         p -> exception_table[i].handler_pc = get_u2();
  275.         p -> exception_table[i].catch_type = get_u2();
  276.     }
  277.     u2 attributes_count = get_u2();
  278.     p -> attributes.resize(attributes_count);
  279.     for (i = 0; i < attributes_count; i++)
  280.         p -> attributes[i] = get_attribute_info();
  281.  
  282.     return p;
  283. }
  284.  
  285. LineNumberTable_attribute *InputClassFile::get_LineNumberTable_attribute(u2 &name_index, u4 &length)
  286. {
  287.     LineNumberTable_attribute *p = new LineNumberTable_attribute(name_index, length);
  288.  
  289.     u2 line_number_table_length = get_u2();
  290.     p -> line_number_table.resize(line_number_table_length);
  291.     for (int i = 0; i < line_number_table_length; i++)
  292.     {
  293.         p -> line_number_table[i].start_pc = get_u2();
  294.         p -> line_number_table[i].line_number = get_u2();
  295.     }
  296.  
  297.     return p;
  298. }
  299.  
  300.  
  301. LocalVariableTable_attribute *InputClassFile::get_LocalVariableTable_attribute(u2 &name_index, u4 &length)
  302. {
  303.     LocalVariableTable_attribute *p = new LocalVariableTable_attribute(name_index, length);
  304.  
  305.     u2 local_variable_table_length = get_u2();
  306.     p -> local_variable_table.resize(local_variable_table_length);
  307.     for (int i = 0; i < local_variable_table_length; i++)
  308.     {
  309.         p -> local_variable_table[i].start_pc = get_u2();
  310.         p -> local_variable_table[i].length = get_u2();
  311.         p -> local_variable_table[i].name_index = get_u2();
  312.         p -> local_variable_table[i].descriptor_index = get_u2();
  313.         p -> local_variable_table[i].index = get_u2();
  314.     }
  315.  
  316.     return p;
  317. }
  318.  
  319. InnerClasses_attribute *InputClassFile::get_InnerClasses_attribute(u2 &name_index, u4 &length)
  320. {
  321.     InnerClasses_attribute *p = new InnerClasses_attribute(name_index, length);
  322.  
  323.     u2 inner_classes_length = get_u2();
  324.     p -> inner_classes.resize(inner_classes_length);
  325.     for (int i = 0; i < inner_classes_length; i++)
  326.     {
  327.         p -> inner_classes[i].inner_class_info_index = get_u2();
  328.         p -> inner_classes[i].outer_class_info_index = get_u2();
  329.         p -> inner_classes[i].inner_name_index = get_u2();
  330.         p -> inner_classes[i].inner_class_access_flags = get_u2();
  331.     }
  332.  
  333.     return p;
  334. }
  335.  
  336. Synthetic_attribute *InputClassFile::get_Synthetic_attribute(u2 &name_index, u4 &length)
  337. {
  338.     Synthetic_attribute *p = new Synthetic_attribute(name_index, length);
  339.  
  340.  
  341.     return p;
  342. }
  343.  
  344. Deprecated_attribute *InputClassFile::get_Deprecated_attribute(u2 &name_index, u4 &length)
  345. {
  346.     Deprecated_attribute *p = new Deprecated_attribute(name_index, length);
  347.  
  348.  
  349.     return p;
  350. }
  351.  
  352.  
  353. GenericAttribute_info *InputClassFile::get_GenericAttribute(u2 &name_index, u4 &length)
  354. {
  355.     GenericAttribute_info *p = new GenericAttribute_info(name_index, length);
  356.  
  357.     p -> info.resize(length);
  358.     for (int i = 0; i < length; i++)
  359.         p -> info[i] = get_u1();
  360.  
  361.     return p;
  362. }
  363.  
  364. attribute_info *InputClassFile::get_attribute_info()
  365. {
  366.     u2 name_index = get_u2();
  367.     u4 length = get_u4();
  368.  
  369.     cp_info *p = constant_pool[name_index];
  370.     CONSTANT_Utf8_info *q = (CONSTANT_Utf8_info *) p;
  371.  
  372.     switch(q -> length())
  373.     {
  374.         case 4:
  375.              {
  376.                                if (strcmp(q -> bytes, "Code") == 0)
  377.                      return get_Code_attribute(name_index, length);
  378.                  else
  379.                      /* crash !!! */ ;
  380.              }
  381.              break;
  382.         case 9:
  383.              {
  384.                  if (strcmp(q -> bytes, "Synthetic") == 0)
  385.                       return get_Synthetic_attribute(name_index, length);
  386.                  else
  387.                      /* crash !!! */ ;
  388.              }
  389.              break;
  390.         case 10:
  391.              {
  392.                  if (strcmp(q -> bytes, "SourceFile") == 0)
  393.                       return get_SourceFile_attribute(name_index, length);
  394.                  else if (strcmp(q -> bytes, "Exceptions") == 0)
  395.                       return get_Exceptions_attribute(name_index, length);
  396.                  else if (strcmp(q -> bytes, "Deprecated") == 0)
  397.                       return get_Deprecated_attribute(name_index, length);
  398.                  else
  399.                      /* crash !!! */ ;
  400.              }
  401.              break;
  402.         case 12:
  403.              {
  404.                  if (strcmp(q -> bytes, "InnerClasses") == 0)
  405.                       return get_InnerClasses_attribute(name_index, length);
  406.                  else
  407.                      /* crash !!! */ ;
  408.              }
  409.              break;
  410.         case 13:
  411.              {
  412.                  if (strcmp(q -> bytes, "ConstantValue") == 0)
  413.                      return get_ConstantValue_attribute(name_index, length);
  414.                  else
  415.                      /* crash !!! */ ;
  416.              }
  417.              break;
  418.         case 15:
  419.              {
  420.                  if (strcmp(q -> bytes, "LineNumberTable") == 0)
  421.                      return get_LineNumberTable_attribute(name_index, length);
  422.                  else
  423.                      /* crash !!! */ ;
  424.              }
  425.              break;
  426.         case 18:
  427.              {
  428.                  if (strcmp(q -> bytes, "LocalVariableTable") == 0)
  429.                      return get_LocalVariableTable_attribute(name_index, length);
  430.                  else
  431.                      /* crash !!! */ ;
  432.              }
  433.              break;
  434.         default:
  435.              /* crash !!! */ ;
  436.              break;
  437.      }
  438.  
  439. cerr << "String \"" << q -> bytes << "\" is not a valid attribute code !!!\n";
  440. exit(1);
  441.  
  442.     return get_GenericAttribute(name_index, length);
  443. }
  444.  
  445.  
  446. void InputClassFile::get_field_info(field_info &f)
  447. {
  448.     f.access_flags = get_u2();
  449.     f.name_index = get_u2();
  450.     f.descriptor_index = get_u2();
  451.  
  452.     u2 attributes_count = get_u2();
  453.     f.attributes.resize(attributes_count);
  454.     for (int i = 0; i < attributes_count; i++)
  455.         f.attributes[i] = get_attribute_info();
  456.  
  457.     return;
  458. }
  459.  
  460.  
  461. void InputClassFile::get_method_info(method_info &m)
  462. {
  463.     m.access_flags = get_u2();
  464.     m.name_index = get_u2();
  465.     m.descriptor_index = get_u2();
  466.  
  467.     u2 attributes_count = get_u2();
  468.     m.attributes.resize(attributes_count);
  469.     for (int i = 0; i < attributes_count; i++)
  470.         m.attributes[i] = get_attribute_info();
  471.  
  472.     return;
  473. }
  474.  
  475.  
  476. InputClassFile::~InputClassFile()
  477. {
  478.     int i;
  479.     for (i = 1; i < constant_pool.length(); i++)
  480.         delete constant_pool[i];
  481.  
  482.     for (i = 0; i < attributes.length(); i++)
  483.         delete attributes[i];
  484.  
  485.     if (classfile)
  486.         fclose(classfile);
  487.  
  488.     return;
  489. }
  490.  
  491. InputClassFile::InputClassFile(char* filename) 
  492. {
  493.     magic = minor_version = major_version = this_class = super_class = 0;
  494.     if ((classfile = fopen(filename, "rb")) == NULL)
  495.         return;
  496.  
  497.     magic = get_u4();
  498.     minor_version = get_u2();
  499.     major_version = get_u2();
  500.  
  501.     u2 constant_pool_count = get_u2();
  502.     constant_pool.resize(constant_pool_count);
  503.     constant_pool[0] = NULL;
  504.     int i;
  505.     for (i = 1; i < constant_pool_count; i++)
  506.     {
  507.         constant_pool[i] = get_cp_info();
  508.         if (constant_pool[i] -> tag == CONSTANT_Long ||
  509.             constant_pool[i] -> tag == CONSTANT_Double)
  510.              constant_pool[++i] = NULL; // skip the next entry for eight-byte constants
  511.     }
  512.  
  513.     access_flags = get_u2();
  514.     this_class = get_u2();
  515.     super_class = get_u2();
  516.  
  517.     u2 interfaces_count = get_u2();
  518.     interfaces.resize(interfaces_count);
  519.     for (i = 0; i < interfaces_count; i++)
  520.         interfaces[i] = get_u2();
  521.  
  522.     u2 fields_count = get_u2();
  523.     fields.resize(fields_count);
  524.     for (i = 0; i < fields_count; i++)
  525.         get_field_info(fields[i]);
  526.  
  527.     u2 methods_count = get_u2();
  528.     methods.resize(methods_count);
  529.     for (i = 0; i < methods_count; i++)
  530.         get_method_info(methods[i]);
  531.  
  532.     u2 attributes_count = get_u2();
  533.     attributes.resize(attributes_count);
  534.     for (i = 0; i < attributes_count; i++)
  535.         attributes[i] = get_attribute_info();
  536.  
  537.     return;
  538. }
  539.  
  540.  
  541.